﻿using System;
using System.Collections.Generic;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YJKArchUtils.ColumnProfileAnalyze;
using YJKArchUtils.Utils;
using YJKArchUtils.Utils.Generics;
using YJKRevitParapet.Controller;

namespace YJKRevitParapet.Analyzer
{
	public class ParapetAnalyzer
	{
		public ParapetAnalyzer(ExternalCommandData cmdData)
		{
			this.m_ComdData = cmdData;
			this.m_UiApp = this.m_ComdData.Application;
			this.m_Doc = cmdData.Application.ActiveUIDocument.Document;
		}

		public Result GetParapetBaseline(double parapetThickness, ref List<Pole2D> analyzedPolelist)
		{
			this.m_ParapetThickness = parapetThickness;
			List<Pole2D> wallInfosByProject = this.GetWallInfosByProject();
			TopPoleAnalyzer topPoleAnalyzer = new TopPoleAnalyzer(this.m_ComdData);
			List<Pole2D> list = new List<Pole2D>();
			if (!topPoleAnalyzer.Analyse(wallInfosByProject, ref list))
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			List<int> list2 = new List<int>();
			List<List<Pole2D>> list3 = new List<List<Pole2D>>();
			this.SortOutByFloor(list, ref list2, ref list3);
			this.FilterOutInternalWalls(ref list2, ref list3);
			this.OperateWallEndsWithColumn(ref list2, ref list3);
			this.FilterShortWall(ref list2, ref list3);
			this.OffsetWithExternalWallDirection(ref list2, ref list3);
			this.MergeEdge(ref list2, ref list3);
			list.Clear();
			foreach (List<Pole2D> list4 in list3)
			{
				foreach (Pole2D pole2D in list4)
				{
					try
					{
						if (YJKRevitParapet.Controller.ExtensibleStorageManager.HasParapetExtensibleStorage(this.m_Doc.GetElement(pole2D.ComponentId) as Wall))
						{
							continue;
						}
					}
					catch (Exception)
					{
						continue;
					}
					analyzedPolelist.Add(pole2D);
				}
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private void SortOutByFloor(List<Pole2D> analyzedPolelist, ref List<int> levelList, ref List<List<Pole2D>> wallListByLevel)
		{
			Dictionary<int, List<Pole2D>> dictionary = new Dictionary<int, List<Pole2D>>();
			foreach (Pole2D pole2D in analyzedPolelist)
			{
				int integerValue = (this.m_Doc.GetElement(pole2D.ComponentId) as Wall).get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT).AsElementId().IntegerValue;
				if (!dictionary.ContainsKey(integerValue))
				{
					dictionary.Add(integerValue, new List<Pole2D>
					{
						pole2D
					});
				}
				else
				{
					dictionary[integerValue].Add(pole2D);
				}
			}
			levelList = dictionary.Keys.ToList<int>();
			wallListByLevel = dictionary.Values.ToList<List<Pole2D>>();
		}

		private void FilterOutInternalWalls(ref List<int> levelList, ref List<List<Pole2D>> wallListByLevel)
		{
			for (int i = 0; i < levelList.Count; i++)
			{
				Level level = this.m_Doc.GetElement(new ElementId(levelList[i])) as Level;
				List<RoomData> roomDataList = new List<RoomData>();
				if (this.GetRoomDataInfos(level, ref roomDataList))
				{
					List<Pole2D> list = wallListByLevel[i];
					for (int j = 0; j < list.Count; j++)
					{
						Pole2D wallInfo = list[j];
						if (!this.IsExternalWall(wallInfo, roomDataList))
						{
							wallListByLevel[i].RemoveAt(j);
							j--;
						}
					}
				}
			}
		}

		private void FilterShortWall(ref List<int> levelList, ref List<List<Pole2D>> wallListByLevel)
		{
			for (int i = 0; i < levelList.Count; i++)
			{
				List<Pole2D> list = wallListByLevel[i];
				Dictionary<XYZ, Node2D> dictionary = new Dictionary<XYZ, Node2D>(new XYZComparer());
				foreach (Pole2D pole2D in list)
				{
					XYZ xyz = pole2D.StartPoint;
					if (!dictionary.ContainsKey(xyz))
					{
						Node2D value = new Node2D(xyz, new List<Pole2D>
						{
							pole2D
						});
						dictionary.Add(xyz, value);
					}
					else
					{
						dictionary[xyz].AddPole(pole2D, false);
					}
					xyz = pole2D.EndPoint;
					if (!dictionary.ContainsKey(xyz))
					{
						Node2D value2 = new Node2D(xyz, new List<Pole2D>
						{
							pole2D
						});
						dictionary.Add(xyz, value2);
					}
					else
					{
						dictionary[xyz].AddPole(pole2D, false);
					}
				}
				List<Node2D> list2 = dictionary.Values.ToList<Node2D>();
				List<Pole2D> list3 = new List<Pole2D>();
				foreach (Pole2D pole2D2 in list)
				{
					XYZ ptStart = pole2D2.StartPoint;
					int num = list2.FindIndex((Node2D node) => Geometry.IsEqual(node.Position, ptStart));
					if (num != -1 && list2[num].PoleList.Count > 1)
					{
						list3.Add(pole2D2);
					}
					else
					{
						XYZ ptEnd = pole2D2.EndPoint;
						int num2 = list2.FindIndex((Node2D node) => Geometry.IsEqual(node.Position, ptEnd));
						if (num2 != -1 && list2[num2].PoleList.Count > 1)
						{
							list3.Add(pole2D2);
						}
					}
				}
				wallListByLevel[i] = list3;
			}
		}

		private void OffsetWithExternalWallDirection(ref List<int> levelList, ref List<List<Pole2D>> wallListByLevel)
		{
			for (int i = 0; i < levelList.Count; i++)
			{
				this.m_Doc.GetElement(new ElementId(levelList[i]));
				List<Pole2D> list = wallListByLevel[i];
				List<Pole2D> list2 = new List<Pole2D>();
				foreach (Pole2D pole2D in list)
				{
					double num = Math.Abs(this.m_ParapetThickness - pole2D.Width) / 2.0;
					Curve curve = pole2D.CenterCurve();
					if (!(null == curve))
					{
						Pole2D pole2D2 = Pole2D.TransformWallToStructure2DPole(curve, pole2D.ComponentId, pole2D.Elevation, num, num);
						pole2D2.IsPositiveDirection = pole2D.IsPositiveDirection;
						list2.Add(pole2D2);
					}
				}
				new TopPoleAnalyzer(this.m_ComdData).FormatDoubleLine(ref list2);
				List<Pole2D> list3 = new List<Pole2D>();
				foreach (Pole2D pole2D3 in list2)
				{
					double num2 = this.m_ParapetThickness / 2.0;
					try
					{
						Pole2D item;
						if (pole2D3.IsPositiveDirection || pole2D3.IsArcPole)
						{
							item = Pole2D.TransformWallToStructure2DPole(pole2D3.NegativeCurve(), pole2D3.ComponentId, pole2D3.Elevation, num2, num2);
						}
						else
						{
							item = Pole2D.TransformWallToStructure2DPole(pole2D3.ReversePositiveCurve(), pole2D3.ComponentId, pole2D3.Elevation, num2, num2);
						}
						list3.Add(item);
					}
					catch (Exception)
					{
					}
				}
				wallListByLevel[i] = list3;
			}
		}

		private void MergeEdge(ref List<int> levelList, ref List<List<Pole2D>> wallListByLevel)
		{
			for (int i = 0; i < levelList.Count; i++)
			{
				this.m_Doc.GetElement(new ElementId(levelList[i]));
				List<Pole2D> poleList = wallListByLevel[i];
				TopPoleAnalyzer topPoleAnalyzer = new TopPoleAnalyzer(this.m_ComdData);
				List<Pole2D> value = new List<Pole2D>();
				if (!topPoleAnalyzer.MergeEdge(poleList, ref value))
				{
					return;
				}
				wallListByLevel[i] = value;
			}
		}

		private void OperateWallEndsWithColumn(ref List<int> levelList, ref List<List<Pole2D>> wallListByLevel)
		{
			for (int i = 0; i < levelList.Count; i++)
			{
				Level level = this.m_Doc.GetElement(new ElementId(levelList[i])) as Level;
				List<ColumnProfileInfo> list = new List<ColumnProfileInfo>();
				this.GetColumnDataInfos(level, ref list);
				Dictionary<int, List<KeyValuePair<Pole2D, bool>>> dictionary = new Dictionary<int, List<KeyValuePair<Pole2D, bool>>>();
				List<Pole2D> list2 = wallListByLevel[i];
				for (int j = 0; j < list2.Count; j++)
				{
					Pole2D pole2D = list2[j];
					int key = 0;
					if (this.FindColumnIndexByPoint(pole2D.StartPoint, list, ref key))
					{
						if (!dictionary.ContainsKey(key))
						{
							List<KeyValuePair<Pole2D, bool>> list3 = new List<KeyValuePair<Pole2D, bool>>();
							list3.Add(new KeyValuePair<Pole2D, bool>(pole2D, true));
							dictionary.Add(key, list3);
						}
						else
						{
							dictionary[key].Add(new KeyValuePair<Pole2D, bool>(pole2D, true));
						}
					}
					if (this.FindColumnIndexByPoint(pole2D.EndPoint, list, ref key))
					{
						if (!dictionary.ContainsKey(key))
						{
							List<KeyValuePair<Pole2D, bool>> list4 = new List<KeyValuePair<Pole2D, bool>>();
							list4.Add(new KeyValuePair<Pole2D, bool>(pole2D, false));
							dictionary.Add(key, list4);
						}
						else
						{
							dictionary[key].Add(new KeyValuePair<Pole2D, bool>(pole2D, false));
						}
					}
				}
				foreach (KeyValuePair<int, List<KeyValuePair<Pole2D, bool>>> keyValuePair in dictionary)
				{
					ColumnProfileInfo columnInfo = list[keyValuePair.Key];
					List<KeyValuePair<Pole2D, bool>> value = keyValuePair.Value;
					this.OperateWallEndsWithOneColumn(columnInfo, value);
				}
			}
		}

		private void OperateWallEndsWithOneColumn(ColumnProfileInfo columnInfo, List<KeyValuePair<Pole2D, bool>> nodePoleList)
		{
			XYZ location = columnInfo.Location;
			for (int i = 0; i < nodePoleList.Count; i++)
			{
				for (int j = i + 1; j < nodePoleList.Count; j++)
				{
					Pole2D key = nodePoleList[i].Key;
					Pole2D key2 = nodePoleList[j].Key;
					double dSAngle = 0.0;
					double dEAngle = 0.0;
					key.GetAngle(location, ref dSAngle);
					key2.GetAngle(location, ref dEAngle);
					if (Geometry.IsEqual(Geometry.BetweenTheAngles(dSAngle, dEAngle, true), Math.PI))
					{
						this.TrimParallelPoleline(location, ref key, nodePoleList[i].Value, ref key2, nodePoleList[j].Value);
					}
					else
					{
						this.TrimIntersectingPoleline(location, ref key, nodePoleList[i].Value, ref key2, nodePoleList[j].Value);
					}
				}
			}
		}

		private void TrimParallelPoleline(XYZ position, ref Pole2D pole1, bool isStart1, ref Pole2D pole2, bool isStart2)
		{
			if (Geometry.IsEqual(pole1.Length(), 0.0) || Geometry.IsEqual(pole2.Length(), 0.0))
			{
				return;
			}
			XYZ xyz = pole1.CurStartPoint(position);
			XYZ xyz2 = pole1.CurEndPoint(position);
			if (Geometry.IsEqual(xyz, xyz2))
			{
				return;
			}
			XYZ xyz3 = pole2.CurStartPoint(position);
			XYZ xyz4 = pole2.CurEndPoint(position);
			if (Geometry.IsEqual(xyz3, xyz4))
			{
				return;
			}
			if (pole1.IsArcPole && pole2.IsArcPole)
			{
				return;
			}
			if (pole1.IsArcPole)
			{
				XYZ newPosition;
				if (isStart1)
				{
					newPosition = Geometry.CalculateFootPoint(xyz3, xyz4, xyz);
				}
				else
				{
					newPosition = Geometry.CalculateFootPoint(xyz3, xyz4, xyz2);
				}
				pole2 = this.ChangeWallEnds(pole2, isStart2, newPosition);
				return;
			}
			if (pole2.IsArcPole)
			{
				XYZ newPosition2;
				if (isStart2)
				{
					newPosition2 = Geometry.CalculateFootPoint(xyz, xyz2, xyz3);
				}
				else
				{
					newPosition2 = Geometry.CalculateFootPoint(xyz, xyz2, xyz4);
				}
				pole1 = this.ChangeWallEnds(pole1, isStart1, newPosition2);
				return;
			}
			XYZ ptStart = xyz;
			XYZ ptEnd;
			if (isStart2)
			{
				ptEnd = Geometry.CalculateFootPoint(xyz, xyz2, xyz3);
			}
			else
			{
				ptEnd = Geometry.CalculateFootPoint(xyz, xyz2, xyz4);
			}
			if (!isStart1)
			{
				ptStart = xyz2;
			}
			XYZ xyz5 = Geometry.CalculatMidPoint(ptStart, ptEnd);
			XYZ newPosition3 = Geometry.CalculateFootPoint(xyz3, xyz4, xyz5);
			pole1 = this.ChangeWallEnds(pole1, isStart1, xyz5);
			pole2 = this.ChangeWallEnds(pole2, isStart2, newPosition3);
		}

		private void TrimIntersectingPoleline(XYZ position, ref Pole2D pole1, bool isStart1, ref Pole2D pole2, bool isStart2)
		{
			if (Geometry.IsEqual(pole1.Length(), 0.0) || Geometry.IsEqual(pole2.Length(), 0.0))
			{
				return;
			}
			XYZ xyz = pole1.CurStartPoint(position);
			XYZ xyz2 = pole1.CurEndPoint(position);
			if (xyz == null || xyz2 == null)
			{
				return;
			}
			if (Geometry.IsEqual(xyz, xyz2))
			{
				return;
			}
			Curve curve;
			if (pole1.IsArcPole)
			{
				XYZ center = pole1.Center;
				XYZ xyz3 = Geometry.CalculatMidPoint(xyz, xyz2, center, XYZ.BasisZ);
				curve = Arc.Create(xyz, xyz2, xyz3);
			}
			else
			{
				curve = Line.CreateBound(xyz, xyz2);
			}
			XYZ xyz4 = pole2.CurStartPoint(position);
			XYZ xyz5 = pole2.CurEndPoint(position);
			if (xyz4 == null || xyz5 == null)
			{
				return;
			}
			if (Geometry.IsEqual(xyz4, xyz5))
			{
				return;
			}
			Curve curve2;
			if (pole2.IsArcPole)
			{
				XYZ center2 = pole2.Center;
				XYZ xyz6 = Geometry.CalculatMidPoint(xyz4, xyz5, center2, XYZ.BasisZ);
				curve2 = Arc.Create(xyz4, xyz5, xyz6);
			}
			else
			{
				curve2 = Line.CreateBound(xyz4, xyz5);
			}
			XYZ xyz7 = Geometry.IntersectWithTwoCurves(curve, curve2, position, true, true, this.m_UiApp.Application);
			if (xyz7 != null)
			{
				pole1 = this.ChangeWallEnds(pole1, isStart1, xyz7);
				pole2 = this.ChangeWallEnds(pole2, isStart2, xyz7);
			}
		}

		private Pole2D ChangeWallEnds(Pole2D wallInfo, bool isStartPoint, XYZ newPosition)
		{
			if (isStartPoint)
			{
				wallInfo.StartPoint = newPosition;
			}
			else
			{
				wallInfo.EndPoint = newPosition;
			}
			return wallInfo;
		}

		private bool FindColumnIndexByPoint(XYZ pt, List<ColumnProfileInfo> columnProfileLoopList, ref int columnProfileLoopIndex)
		{
			for (int i = 0; i < columnProfileLoopList.Count; i++)
			{
				if (columnProfileLoopList[i].IsInside(pt, true))
				{
					columnProfileLoopIndex = i;
					return true;
				}
			}
			return false;
		}

		private bool IsExternalWall(Pole2D wallInfo, List<RoomData> roomDataList)
		{
			int integerValue = wallInfo.ComponentId.IntegerValue;
			bool flag = false;
			bool flag2 = false;
			foreach (RoomData roomData in roomDataList)
			{
				List<RoomData.BoundingSegment> list = new List<RoomData.BoundingSegment>();
				if (roomData.FindWallId(wallInfo.ComponentId, ref list))
				{
					foreach (RoomData.BoundingSegment boundingSegment in list)
					{
						if (!boundingSegment.Curve.IsArc && !wallInfo.IsArcPole)
						{
							EdgeInfo curve = boundingSegment.Curve;
							XYZ xyz = null;
							XYZ xyz2 = null;
							Geometry.OverlapType overlapType = Geometry.IsOverlapOfTwoLine(this.Point2d(curve.StartPoint), this.Point2d(curve.EndPoint), this.Point2d(wallInfo.PositiveStartPoint), this.Point2d(wallInfo.PositiveEndPoint), ref xyz, ref xyz2, true, 1E-09);
							if (overlapType != Geometry.OverlapType._OT_None && overlapType != Geometry.OverlapType._OT_Linked)
							{
								flag = true;
							}
							overlapType = Geometry.IsOverlapOfTwoLine(this.Point2d(curve.StartPoint), this.Point2d(curve.EndPoint), this.Point2d(wallInfo.NegativeStartPoint), this.Point2d(wallInfo.NegativeEndPoint), ref xyz, ref xyz2, true, 1E-09);
							if (overlapType != Geometry.OverlapType._OT_None && overlapType != Geometry.OverlapType._OT_Linked)
							{
								flag2 = true;
							}
						}
						else if (boundingSegment.Curve.IsArc && wallInfo.IsArcPole)
						{
							EdgeInfo curve2 = boundingSegment.Curve;
							XYZ xyz3 = curve2.StartPoint;
							XYZ xyz4 = curve2.EndPoint;
							XYZ pt = null;
							Geometry.GetCenterWithBulge(xyz3, xyz4, curve2.Bulge, ref pt);
							if (Geometry.LessThan(curve2.Bulge, 0.0))
							{
								if (Geometry.GreaterThan(wallInfo.Bulge, 0.0))
								{
									xyz3 = curve2.EndPoint;
									xyz4 = curve2.StartPoint;
								}
							}
							else if (Geometry.LessThan(wallInfo.Bulge, 0.0))
							{
								xyz3 = curve2.EndPoint;
								xyz4 = curve2.StartPoint;
							}
							XYZ center = wallInfo.Center;
							XYZ xyz5 = null;
							XYZ xyz6 = null;
							Geometry.OverlapType overlapType2 = Geometry.IsOverlapOfTwoArc(this.Point2d(xyz3), this.Point2d(xyz4), this.Point2d(pt), this.Point2d(wallInfo.PositiveStartPoint), this.Point2d(wallInfo.PositiveEndPoint), this.Point2d(center), ref xyz5, ref xyz6, 1E-09);
							if (overlapType2 != Geometry.OverlapType._OT_None && overlapType2 != Geometry.OverlapType._OT_Linked)
							{
								flag = true;
							}
							overlapType2 = Geometry.IsOverlapOfTwoArc(this.Point2d(xyz3), this.Point2d(xyz4), this.Point2d(pt), this.Point2d(wallInfo.NegativeStartPoint), this.Point2d(wallInfo.NegativeEndPoint), this.Point2d(center), ref xyz5, ref xyz6, 1E-09);
							if (overlapType2 != Geometry.OverlapType._OT_None && overlapType2 != Geometry.OverlapType._OT_Linked)
							{
								flag2 = true;
							}
						}
					}
					if (flag && flag2)
					{
						return false;
					}
				}
			}
			if (flag)
			{
				wallInfo.IsPositiveDirection = false;
			}
			if (flag2)
			{
				wallInfo.IsPositiveDirection = true;
			}
			return true;
		}

		private XYZ Point2d(XYZ pt)
		{
			return new XYZ(pt.X, pt.Y, 0.0);
		}

		private void GetColumnDataInfos(Level level, ref List<ColumnProfileInfo> columnProfileLoopList)
		{
			new ColumnProfileAnalyzer(this.m_ComdData).GetCurrentLayerColumeInfos(ref columnProfileLoopList);
		}

		private bool GetRoomDataInfos(Level level, ref List<RoomData> roomDataList)
		{
			Transaction transaction = null;
			bool result;
			try
			{
				transaction = new Transaction(this.m_Doc);
				transaction.Start("get room data");
				this.RemoveRooms(level);
				roomDataList = this.Create2ndGetRoomDataInfos(level);
				if (transaction != null && transaction.HasStarted() && !transaction.HasEnded())
				{
					transaction.RollBack();
				}
				result = true;
			}
			catch (Exception)
			{
				if (transaction != null && transaction.HasStarted() && !transaction.HasEnded())
				{
					transaction.RollBack();
				}
				result = false;
			}
			return result;
		}

		private void RemoveRooms(Level level)
		{
			Autodesk.Revit.DB.View view = null;
			if (!this.GetFloorPlanViewByLevel(level, ref view))
			{
				return;
			}
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_Doc, view.Id).OfClass(typeof(SpatialElement));
			List<ElementId> list = new List<ElementId>();
			foreach (Element element in filteredElementCollector)
			{
				Room room = ((SpatialElement)element) as Room;
				if (room != null)
				{
					list.Add(room.Id);
				}
			}
			this.m_Doc.Delete(list);
		}

		private bool GetFloorPlanViewByLevel(Level level, ref Autodesk.Revit.DB.View floorPlanView)
		{
			foreach (Element element in new FilteredElementCollector(this.m_Doc).OfClass(typeof(Autodesk.Revit.DB.View)).ToElements())
			{
				Autodesk.Revit.DB.View view = element as Autodesk.Revit.DB.View;
				if (!(view.GetType() != typeof(ViewPlan)))
				{
					ViewPlan viewPlan = view as ViewPlan;
					if ((int)viewPlan.ViewType == 1 && viewPlan.GenLevel != null && Geometry.IsEqual(view.GenLevel.Elevation, level.Elevation))
					{
						floorPlanView = view;
						return true;
					}
				}
			}
			return false;
		}

		private List<RoomData> Create2ndGetRoomDataInfos(Level level)
		{
			List<RoomData> list = new List<RoomData>();
			double num = AssistFunc.mmToFeet(500.0);
			num *= num;
			SpatialElementBoundaryOptions spatialElementBoundaryOptions = new SpatialElementBoundaryOptions();
			foreach (object obj in this.m_Doc.get_PlanTopology(level).Circuits)
			{
				PlanCircuit planCircuit = (PlanCircuit)obj;
				if (!planCircuit.IsRoomLocated && !Geometry.LessThan(planCircuit.Area, num))
				{
					SpatialElement spatialElement = this.m_Doc.Create.NewRoom(null, planCircuit);
					List<RoomData.BoundingSegment> list2 = new List<RoomData.BoundingSegment>();
					foreach (IList<BoundarySegment> list3 in spatialElement.GetBoundarySegments(spatialElementBoundaryOptions))
					{
						foreach (BoundarySegment segment in list3)
						{
							Element element = segment.GetElement(this.m_Doc);
							if (element != null && !(element.GetType() != typeof(Wall)))
							{
								RoomData.BoundingSegment item = new RoomData.BoundingSegment(new EdgeInfo(segment.GetCurve(), false), element.Id);
								list2.Add(item);
							}
						}
					}
					RoomData item2 = new RoomData(list2);
					list.Add(item2);
				}
			}
			return list;
		}

		private List<Pole2D> GetWallInfosByProject()
		{
			List<ElementId> list = new List<ElementId>();
			List<Wall> list2 = new List<Wall>();
			foreach (Element element in new FilteredElementCollector(this.m_Doc).OfClass(typeof(Wall)).ToElements())
			{
				Wall wall = element as Wall;
				if (this.IsValidWall(wall, ref list))
				{
					list2.Add(wall);
				}
			}
			List<Pole2D> list3 = new List<Pole2D>();
			foreach (Wall wall2 in list2)
			{
				double num = wall2.Width / 2.0;
				double num2 = 0.0;
				double num3 = 0.0;
				ParapetAnalyzer.GetWallElevations(this.m_Doc, wall2, ref num2, ref num3);
				if (!Geometry.LessThan(num3, 0.0))
				{
					Pole2D item = null;
					Curve curve = (wall2.Location as LocationCurve).Curve;
					XYZ ptStart = Pole2D.To2D(curve.GetEndPoint(0));
					XYZ ptEnd = Pole2D.To2D(curve.GetEndPoint(1));
					Line line = curve as Line;
					if (null != line)
					{
						item = Pole2D.NewStructure2DPole(wall2.Id, ptStart, ptEnd, num3, num, num);
					}
					Arc arc = curve as Arc;
					if (null != arc)
					{
						item = Pole2D.NewStructure2DPole(wall2.Id, ptStart, ptEnd, Pole2D.To2D(arc.Center), arc.Normal, num3, num, num);
					}
					list3.Add(item);
				}
			}
			return list3;
		}

		private bool IsValidWall(Wall wall, ref List<ElementId> surfaceLayerTypeIdList)
		{
			WallType wallType = wall.WallType;
			if (wallType == null)
			{
				return false;
			}
			if (wallType.Kind != null)
			{
				return false;
			}
			if (surfaceLayerTypeIdList.FindIndex((ElementId item) => item.IntegerValue == wallType.Id.IntegerValue) != -1)
			{
				return false;
			}
			double num = 0.0;
			double num2 = 0.0;
			ParapetAnalyzer.GetWallElevationInfo(wall, this.m_Doc, ref num, ref num2);
			if (Geometry.Lessthan_Or_Equal(num + num2, 0.0))
			{
				return false;
			}
			CompoundStructure compoundStructure = wallType.GetCompoundStructure();
			if (compoundStructure == null)
			{
				return false;
			}
			IEnumerable<CompoundStructureLayer> layers = compoundStructure.GetLayers();
			bool flag = false;
			IEnumerator<CompoundStructureLayer> enumerator = layers.GetEnumerator();
			{
				while (enumerator.MoveNext())
				{
					if ((int)enumerator.Current.Function == 1)
					{
						flag = true;
						break;
					}
				}
			}
			if (!flag)
			{
				surfaceLayerTypeIdList.Add(wallType.Id);
				return false;
			}
			return true;
		}

		private static void GetWallElevationInfo(Wall wall, Autodesk.Revit.DB.Document doc, ref double wallElevation, ref double wallHeight)
		{
			try
			{
				ElementId elementId = wall.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT).AsElementId();
				double elevation = (doc.GetElement(elementId) as Level).Elevation;
				double num = wall.get_Parameter(BuiltInParameter.WALL_BASE_OFFSET).AsDouble();
				wallElevation = elevation + num;
				ElementId elementId2 = wall.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).AsElementId();
				if (elementId2 == ElementId.InvalidElementId)
				{
					double num2 = wall.get_Parameter(BuiltInParameter.WALL_USER_HEIGHT_PARAM).AsDouble();
					wallHeight = num2;
				}
				else
				{
					Level level = doc.GetElement(elementId2) as Level;
					double num3 = wall.get_Parameter(BuiltInParameter.WALL_TOP_OFFSET).AsDouble();
					wallHeight = level.Elevation + num3 - wallElevation;
				}
			}
			catch (Exception ex)
			{
				string message = ex.Message;
			}
		}

		public static void GetWallElevations(Autodesk.Revit.DB.Document doc, Wall wall, ref double bottom, ref double top)
		{
			ElementId elementId = wall.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT).AsElementId();
			Level level = doc.GetElement(elementId) as Level;
			bottom = level.Elevation;
			double num = wall.get_Parameter(BuiltInParameter.WALL_BASE_OFFSET).AsDouble();
			bottom += num;
			ElementId elementId2 = wall.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).AsElementId();
			if (elementId2 == ElementId.InvalidElementId)
			{
				double num2 = wall.get_Parameter(BuiltInParameter.WALL_USER_HEIGHT_PARAM).AsDouble();
				top = bottom + num2;
				return;
			}
			Level level2 = doc.GetElement(elementId2) as Level;
			top = level2.Elevation;
			double num3 = wall.get_Parameter(BuiltInParameter.WALL_TOP_OFFSET).AsDouble();
			top += num3;
		}

		private ExternalCommandData m_ComdData;

		private UIApplication m_UiApp;

		private Document m_Doc;

		private double m_ParapetThickness;
	}
}
